
#pragma once
#include <string>
#include <memory>
#include <stdexcept>
#include <gpiod.h>

#include <linux/types.h>
#include <linux/spi/spidev.h> // 需要安装linux-headers或从内核源获取
#include "yj_return.hpp"
class spi_v1
{
public:
    typedef enum
    {
        spi_mode_0 = SPI_MODE_0,
        spi_mode_1 = SPI_MODE_1,
        spi_mode_2 = SPI_MODE_2,
        spi_mode_3 = SPI_MODE_3
    } spi_mode_en;

private:
    std::string _device_path;
    int _fd; // 文件描述符
    uint32_t _speed_hz;
    uint8_t _mode;
    uint8_t _bits_per_word;

    yj_return _is_open_flag;

    // 内部配置函数，使用 ioctl
    yj_return _configure();

public:
    // 构造函数：打开设备并配置
    spi_v1(std::string device_path,
           uint32_t speed_hz = 1000000,
           spi_mode_en mode = spi_mode_0,
           uint8_t bits_per_word = 8);

    // 析构函数：自动关闭文件描述符 (RAII)
    ~spi_v1();

    // 修改后的传输函数：支持分别定义tx和rx长度
    // - 如果tx_buffer == nullptr 或 tx_length == 0：只接收
    // - 如果rx_buffer == nullptr 或 rx_length == 0：只发送
    // - 如果长度不同：自动填充/忽略以匹配max(tx_length, rx_length)
    yj_return transfer_and_recv(const uint8_t *tx_buffer,
                                size_t tx_length,
                                uint8_t *rx_buffer,
                                size_t rx_length,
                                uint16_t delay_after_send_us = 50);


    // 配置方法（可选，现代化 setter）
    yj_return set_speed(uint32_t speed_hz);
    yj_return set_mode(spi_mode_en mode);
    yj_return set_bits_per_word(uint8_t bits);
    yj_return is_open() { return _is_open_flag; }
};